﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.Reflection;
using System.Xaml;
using NeuroSpeech.XamlExtensions;
using System.Diagnostics;

namespace NeuroSpeech.XamlExtensions
{
    public class DefaultWriter : XamlDirectiveWriter
    {

        public DefaultWriter():base(null)
        {

        }

        public DefaultWriter(XamlDirective dir):base(dir)
        {

        }

        public override void StartObject(XamlCodeContext context)
        {
            DefaultConverter.ExecuteStartObject(context);
        }

        public override void StartMember(XamlCodeContext context)
        {

        }

        #region public override void  WriteEndMember(XamlCodeContext context)
        public override void EndMember(XamlCodeContext context)
        {
            if(context.Peek.IsValueCollection){
                return;
            }

            if (context.Peek.Value.Value == null)
                return;
            XamlItem peek = context.Peek;

            DefaultConverter.SetValue(context);

            /*CodeExpression value = context.XamlValue.Value as CodeExpression;
            if (value == null)
                value = Transform(peek, context.XamlValue.Value);
            CodeAssignStatement
                cas = new CodeAssignStatement
                {
                    Left = peek.TargetObject,
                    Right = value
                };
            context.InitMethod.Statements.Add(cas);
            */
            //if (peek.Name != null) {
            //    cas = new CodeAssignStatement
            //    {
            //        Left = new CodeFieldReferenceExpression { 
            //            TargetObject = new CodeThisReferenceExpression(),
            //            FieldName = peek.Name
            //        },
            //        Right = peek.TargetObject
            //    };
            //    context.InitMethod.Statements.Add(cas);
            //}

            //context.Peek.Value.Clear();
            
        }
        #endregion

        //private CodeExpression Transform(XamlItem peek, object value)
        //{
        //    if (peek.Member.UnderlyingMember == null)
        //        return new CodePrimitiveExpression(value);
        //    MemberInfo m = peek.Member.UnderlyingMember;
        //    if (m.MemberType == MemberTypes.Property)
        //    {
        //        PropertyInfo p = m as PropertyInfo;
        //        if (p.PropertyType.IsEnum)
        //        {
        //            return new CodePropertyReferenceExpression
        //            {
        //                PropertyName = value as string,
        //                TargetObject = new CodeTypeReferenceExpression(p.PropertyType)
        //            };
        //        }
        //    }
        //    return new CodePrimitiveExpression(value);
        //}



        #region public override void  WriteEndObject(XamlCodeContext context)
        public override void EndObject(XamlCodeContext context)
        {
            XamlItem peek = context.Peek;
            if (peek.IsRoot) {
                if (peek.Member == null)
                    return;
                context.Peek.Value.SetValue( new CodePropertyReferenceExpression
                {
                    TargetObject = new CodeThisReferenceExpression(),
                    PropertyName = peek.Member.Name
                });
            } else {
                if (peek.Variable != null)
                {
                    context.Peek.Value.SetValue(new CodeVariableReferenceExpression
                    {
                        VariableName = peek.Variable
                    });


                    // set local variable..
                    if (peek.Name != null)
                    {
                        CodeAssignStatement cas = new CodeAssignStatement
                        {
                            Left = new CodeFieldReferenceExpression
                            {
                                TargetObject = new CodeThisReferenceExpression(),
                                FieldName = peek.Name
                            },
                            Right = new CodeVariableReferenceExpression
                            {
                                VariableName = peek.Variable
                            }
                        };
                        context.PreStatements.Add(cas);
                    }

                }
                else {
                    Trace.WriteLine(peek.Depth + " Variable is null... ");
                }
            }
            //context.Value = context.Peek.TargetObject;
        }
        #endregion



    }
}
